﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

#if UNITY_EDITOR
#endif

namespace SG
{
    public class ResourceLoader : MonoBehaviour
    {
        #region      
        static ResourceLoader m_Instance;
        public static ResourceLoader Instance()
        {
            if (m_Instance == null)
            {
                m_Instance = InstanceHelper.Singleton<ResourceLoader>();
                CreateResourceModuleForTest();
            }
            return m_Instance;
        }

        public static void CreateResourceModuleForTest()
        {
            // 如果游戏模块没有创建
            //if (MotionFramework.MotionEngine.Contains(typeof(ResourceManager)) == false)
            //{
            //    var localBundleServices = new LocalBundleServices();
            //    // 创建测试资源管理器
            //    var resourceCreateParam = new ResourceManager.CreateParameters()
            //    {                        
            //        LocationRoot = GameDefine.AssetRootPath,
            //        SimulationOnEditor = true,
            //        BundleServices = localBundleServices,
            //        DecryptServices = new Decrypter(),
            //        AutoReleaseInterval = -1f                   
            //    };
            //    MotionFramework.MotionEngine.CreateModule<ResourceManager>(resourceCreateParam);
            //}
        }

        #endregion

        private readonly Dictionary<string, ResourceCollector> _collectors = new Dictionary<string, ResourceCollector>();

        public IEnumerator Cleanup()
        {
            // 等待所有请求完成
            // 要是不等待Unity很多版本都有各种Bug
            yield return new WaitUntil(() =>
            {
                return IsAllDone;
            });
            DestroyAll();
            //ResourceManager.Instance.UnloadUnusedAssets();       
        }

        public bool IsAllDone
        {
            get
            {
                //foreach (var pair in _collectors)
                //{
                //    if (pair.Value.IsDone == false)
                //        return false;
                //}
                return true;
            }
        }

        /// <summary>
        /// 销毁所有对象池及其资源
        /// </summary>
        public void DestroyAll()
        {
            List<ResourceCollector> removeList = new List<ResourceCollector>();
            foreach (var pair in _collectors)
            {
                if (pair.Value.DontDestroy == false)
                    removeList.Add(pair.Value);
            }

            // 移除并销毁
            foreach (var collector in removeList)
            {
                _collectors.Remove(collector.Location);
                collector.Destroy();
            }
        }

        public T LoadAsset<T>(string path, bool dontDestory = false) where T : UnityEngine.Object
        {
            //#if UNITY_EDITOR
            //收集 加载 资源
            // ResourceLoaderViewerData.Instance().AddLoaderPath(path);
            //#endif
            return Resources.Load<T>(path);
            var obj = GetObjectFromPool<T>(path);
            if (obj != null)
            {
                return obj;
            }
            return DoLoadResource<T>(path, dontDestory);
        }

        public void LoadAssetAsync<T>(string path, Action<T> _callBack, bool _dontDestory = false) where T : UnityEngine.Object
        {
            //#if UNITY_EDITOR
            //收集 加载 资源
            // ResourceLoaderViewerData.Instance().AddLoaderPath(path);
            //#endif
            var obj = GetObjectFromPool<T>(path);
            if (obj != null)
            {
                _callBack?.Invoke(obj);
                return;
            }
            //DoLoadResourceAysnc<T>(path, (handle) =>
            //{
            //    SetResourceCollectorObject(path, (T)handle.AssetObject);
            //    _callBack?.Invoke(GetObjectFromPool<T>(path));

            //}, _dontDestory);
        }

        //private void DoLoadResourceAysnc<T>(string path, Action<AssetOperationHandle> completed = null, bool dontDestory = false)
        //{
        //    var s = GetResourceCollector(path);
        //    if (s != null && s._handles.Count > 0)
        //    {
        //        s._handles[0].Completed += completed;
        //    }
        //    else
        //    {
        //        var handle = ResourceManager.Instance.LoadAssetAsync<T>(path);
        //        AddCollector(path, handle, dontDestory);
        //        handle.Completed += completed;
        //    }
        //}

        private T GetObjectFromPool<T>(string path) where T : UnityEngine.Object
        {
            var tempCollector = GetResourceCollector(path);
            if (tempCollector != null)
            {
                var obj = tempCollector._object as T;
                if (obj != null)
                    return obj;
            }
            return null;
        }
        //private void AddCollector(string location, AssetOperationHandle handle, bool dontDestory = false)
        //{
        //    if (_collectors.ContainsKey(location))
        //    {
        //        ResourceCollector collector = _collectors[location];
        //        collector._handles.Add(handle);
        //    }
        //    else
        //    {
        //        ResourceCollector collector = new ResourceCollector
        //        {
        //            Location = location,
        //            DontDestroy = dontDestory
        //        };
        //        collector._handles.Add(handle);
        //        _collectors.Add(location, collector);
        //    }
        //}

        private ResourceCollector GetResourceCollector(string location)
        {
            if (_collectors.ContainsKey(location))
            {
                return _collectors[location];
            }
            return null;
        }

        private void SetResourceCollectorObject(string path, UnityEngine.Object _obj)
        {
            var collector = GetResourceCollector(path);
            if (collector != null)
            {
                collector._object = _obj;
            }
            else
            {
                XKLog.LogError("ResourceCollector is null :" + path);
            }
        }

        private T DoLoadResource<T>(string path, bool dontDestory = false) where T : UnityEngine.Object
        {
            //var handle = ResourceManager.Instance.LoadAssetSync<T>(path);
            //AddCollector(path, handle, dontDestory);
            //SetResourceCollectorObject(path, (T)handle.AssetObject);
            return GetObjectFromPool<T>(path);
        }

        public TextAsset LoadLua(string filepath)
        {
            filepath = filepath.Replace("\\", "/");
            filepath = filepath.Replace(".lua", "");
            TextAsset luaCfg = LoadAsset<TextAsset>(filepath + ".lua");

            if (luaCfg != null)
            {
                ProfilerData.AddLuaFile(filepath, luaCfg);
            }
            if (luaCfg != null)
            {
                return luaCfg;
            }
            return null;
        }
    }
}


